package cn.haigui.icrawler.core.downloader;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

public class DefaultDownloaderFactory implements IDownloaderFactory{

    Class<? extends IDownloader> downloaderType;
    List<IDownloader> downloaders=new ArrayList<>();
    Object[] params=new Object[0];

    public DefaultDownloaderFactory(){
        this.downloaderType=JsoupDownloader.class;
    }

    public DefaultDownloaderFactory(Class<? extends IDownloader> downloaderType){
        this.downloaderType=downloaderType;
    }

    public DefaultDownloaderFactory(Object... params){
        this.params=params;
    }

    public DefaultDownloaderFactory(Class<? extends IDownloader> downloaderType,Object... params){
        this.downloaderType=downloaderType;
        this.params=params;
    }


    protected <T> T newInstance(Class<T> t, Object... params){
        T result = null;
        for (Constructor<?> constructor : t.getConstructors()) {
            if (constructor.getParameters().length!=params.length){
                continue;
            }
            try{
                result= (T) constructor.newInstance(params);
                break;
            }catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        if (result==null){
            throw new RuntimeException("new 下载器失败，参数类型或个数对不上");
        }
        return result;
    }


    @Override
    public IDownloader get() {
        IDownloader iDownloader = newInstance(downloaderType, params);
        downloaders.add(iDownloader);
        return iDownloader;
    }

    /**
     * 关闭池子
     */
    @Override
    public void quit() {
        for (IDownloader downloader : downloaders) {
            downloader.quit();
        }
    }

    @Override
    public IDownloaderFactory setDownloaderType(Class<? extends IDownloader> downloaderType) {
         this.downloaderType=downloaderType;
         return this;
    }
}
